﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFileDialog>
#include <QProcess>
#include <QDebug>
#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
	setConnectHandles();
	init();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setConnectHandles()
{
	connect(ui->openGitDirButton, &QPushButton::clicked, [=]() {
		QString dirString = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
			ui->gitDirLineEdit->text(),
			QFileDialog::ShowDirsOnly
			| QFileDialog::DontResolveSymlinks);

		ui->gitDirLineEdit->setText(dirString);
	});

	connect(ui->gitDirLineEdit, &QLineEdit::textChanged, [=](const QString &text) {
		QString reportDir;
		QDir dir(text);
		if (dir.isRoot() == false)
			dir.cdUp();

		ui->reportDirLineEdit->setText(dir.absolutePath());
	});

	connect(ui->reportDirButton, &QPushButton::clicked, [=]() {
		QString dirString = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
			"./",
			QFileDialog::ShowDirsOnly
			| QFileDialog::DontResolveSymlinks);

		ui->reportDirLineEdit->setText(dirString);
	});

	connect(ui->beginDateEdit, &QDateEdit::dateChanged, [=](const QDate &date) {
		ui->endDateEdit->setDate(date.addDays(6));
	});

	connect(ui->okButton, &QPushButton::clicked, [=]() {
        QString author = ui->authorLineEdit->text();
        if(author.isEmpty() == true)
        {
            QMessageBox::information(this, u8"提示", u8"请输入作者",
                                        QMessageBox::Yes);
            return;
        }

        mapToSave.clear();
		auto gitPath = ui->gitDirLineEdit->text();
		auto reportDir = ui->reportDirLineEdit->text();
        beginDateTime_ = QDateTime(ui->beginDateEdit->date(), QTime(0, 0, 0));
        endDateTime_ = QDateTime(ui->endDateEdit->date(), QTime(23, 59, 59));

		auto beginDateTime = beginDateTime_.addDays(-2);
		auto endDateTime = endDateTime_.addDays(2);

        QString format = QString(" --pretty=format:%cd%1%s%2 ").arg(TIME_CONTENT_SEPARATOR).arg(LINE_SEPARATOR);

        author = QString(" --author=") + author;

        QString time = QString(" --since=\"%1\" --before=\"%2\" ")
                .arg(beginDateTime.toString("yyyy-M-d"))
                .arg(endDateTime.toString("yyyy-M-d"));

        const QString logDateFormat = " --date=format:%Y-%m-%d-%H-%M-%S ";
		const QString noMerges = " --no-merges ";
		const QString branch = ui->branchLineEdit->text();

        QString gitCmd = QString("git log %1 ").arg(branch)
			+ noMerges + time + logDateFormat + format + author;

		QDir::setCurrent(gitPath);
		QProcess p(this);
		p.start("cmd", QStringList() << "/c" << gitCmd);
		p.waitForStarted();
		p.waitForFinished();
		QString result = p.readAllStandardOutput();
		if (result.isEmpty() == true)
		{
			QMessageBox::information(this, u8"提示", u8"日志结果为空",
				QMessageBox::Yes);
			return;
		}

		auto resultPath = reportDir + "/" + generateFileName() + ".txt";
        parseData(result);
        saveFile(resultPath);
		QMessageBox::information(this, u8"提示", QString(u8"已保存为 \"%1\"").arg(resultPath),
			QMessageBox::Yes);
	});
}

void MainWindow::init()
{
	ui->gitDirLineEdit->setFocusPolicy(Qt::NoFocus);
    ui->gitDirLineEdit->setText(QCoreApplication::applicationDirPath());
	ui->reportDirLineEdit->setFocusPolicy(Qt::NoFocus);

	auto currentDate = QDate::currentDate();
    ui->beginDateEdit->setDate(currentDate.addDays(-6));

	QProcess p(this);
	p.start("cmd", QStringList() << "/c" << "git config user.name");
	p.waitForStarted();
	p.waitForFinished();
	QString author = p.readAllStandardOutput();
	ui->authorLineEdit->setText(author.trimmed());
}

void MainWindow::parseOneContent(const QString& _content, const QDateTime _dateTime)
{
	QString content = _content;

	content.replace(u8"：", ":");
	int separatorPosition = content.indexOf(":");

	QString contentToSave;
	QString title;
	if (separatorPosition < 0)
	{
		title = OTHER_TITLE;
		contentToSave = _content;
	}

	auto contentHead = content.split(":")[0];

	auto it = HEAD_MAP.find(contentHead);
	if (HEAD_MAP.end() == it)
	{
		title = OTHER_TITLE;
		contentToSave = _content;
	}
	else
	{
		title = it->second;
		contentToSave = content.mid(contentHead.length() + 1);
	}

	contentToSave = contentToSave.trimmed();
	if (ui->showTimeCheckBox->isChecked() == true)
	{
		auto timeToSave = _dateTime.toString("yyyyMMdd hh:mm:ss");
		contentToSave = timeToSave + "---" + contentToSave;
	}

	mapToSave[title].push_back(contentToSave);
}

void MainWindow::parseData(const QString& _data)
{
    auto logList = _data.split(LINE_SEPARATOR);
    if(logList.size() == 0)
        return;

    for(auto logItem : logList)
    {
        auto logItemList = logItem.split(TIME_CONTENT_SEPARATOR);
        if(logItemList.size() < 2)
            continue;

        auto time = logItemList[0].trimmed();
        auto content = logItemList[1];

        QString format = "yyyy-MM-dd-hh-mm-ss";
		auto dateTime = QDateTime::fromString(time, format);

		if (dateTime >= beginDateTime_ && dateTime <= endDateTime_)
		{
			parseOneContent(content, dateTime);
		}
    }
}

void MainWindow::saveFile(QString _path)
{
	QFile file(_path);

	if (file.open(QFile::WriteOnly | QIODevice::Text) == false)
		return;

    QTextStream out(&file);

    for(auto it : mapToSave)
    {
		if (OTHER_TITLE == it.first)
			continue;

		saveOneTypeFile(out, it);
    }

	auto otherTitleIt = mapToSave.find(OTHER_TITLE);
	if (otherTitleIt!= mapToSave.end())
	{
		saveOneTypeFile(out, *otherTitleIt);
	}

    file.close();
}

QString MainWindow::generateFileName()
{
	QDir gitDir(ui->gitDirLineEdit->text());
	const auto projectName = gitDir.dirName();
	const auto branch = ui->branchLineEdit->text();
	const QString author = ui->authorLineEdit->text();
	const QString beginDateTime = ui->beginDateEdit->date().toString("yyyy-M-d");
	const QString endDateTime = ui->endDateEdit->date().toString("yyyy-M-d");

	QString reportName = projectName + "-" + 
		branch + "-" + 
		author + "-" +
		beginDateTime + "-" +
		endDateTime + u8"报告";

	return reportName;
}

void MainWindow::saveOneTypeFile(QTextStream& _stream, const std::pair<QString, std::vector<QString>> _pair)
{
	_stream << _pair.first << QString("(%1)").arg(_pair.second.size()) << endl;
	for (auto content : _pair.second)
		_stream << content << endl;
	_stream << endl;
}
